<template>
  <div 
    class="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4"
    v-if="visible"
    @click="handleOverlayClick"
  >
    <!-- 模态框容器 -->
    <div 
      class="bg-white rounded-lg shadow-xl w-full max-w-md mx-auto transform transition-all duration-300 scale-100"
      @click.stop
    >
      <!-- 模态框头部 -->
      <div class="px-6 py-4 border-b border-gray-200 flex justify-between items-center">
        <h3 class="text-lg font-medium text-gray-900">新增角色</h3>
        <button 
          class="text-gray-400 hover:text-gray-500 focus:outline-none"
          @click="handleClose"
          aria-label="关闭"
        >
          <i class="fa fa-times"></i>
        </button>
      </div>
      
      <!-- 模态框内容 -->
      <div class="px-6 py-5">
        <form @submit.prevent="handleSubmit">
          <!-- 角色名称 -->
          <div class="mb-4">
            <label for="name" class="block text-sm font-medium text-gray-700 mb-1">
              角色名称 <span class="text-red-500">*</span>
            </label>
            <input
              id="name"
              v-model="formData.name"
              type="text"
              class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-colors"
              :class="errors.name ? 'border-red-500 focus:ring-red-500 focus:border-red-500' : ''"
              placeholder="请输入角色名称"
              autofocus
            >
            <p v-if="errors.name" class="mt-1 text-sm text-red-600">{{ errors.name }}</p>
          </div>
          
          <!-- 角色编码 -->
          <div class="mb-4">
            <label for="code" class="block text-sm font-medium text-gray-700 mb-1">
              角色编码 <span class="text-red-500">*</span>
            </label>
            <input
              id="code"
              v-model="formData.code"
              type="text"
              class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-colors font-mono text-sm"
              :class="errors.code ? 'border-red-500 focus:ring-red-500 focus:border-red-500' : ''"
              placeholder="请输入角色编码（英文/数字/下划线）"
            >
            <p v-if="errors.code" class="mt-1 text-sm text-red-600">{{ errors.code }}</p>
            <div class="mt-1 text-xs text-gray-500 flex items-start">
              <i class="fa fa-info-circle mt-0.5 mr-1 text-blue-500"></i>
              <p>
                用于系统内部标识，建议使用小写字母、数字和下划线，创建后不可修改
              </p>
            </div>
          </div>
          
          <!-- 角色描述 -->
          <div class="mb-4">
            <label for="description" class="block text-sm font-medium text-gray-700 mb-1">
              角色描述
            </label>
            <textarea
              id="description"
              v-model="formData.description"
              rows="3"
              class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-colors"
              placeholder="请输入角色描述信息，说明该角色的职责和权限范围"
            ></textarea>
          </div>
          
          <!-- 角色权限提示 -->
          <div class="bg-blue-50 border-l-4 border-blue-400 p-3 rounded">
            <div class="flex">
              <div class="flex-shrink-0">
                <i class="fa fa-lightbulb text-blue-500"></i>
              </div>
              <div class="ml-3">
                <p class="text-sm text-blue-700">
                  角色创建后，可以在"权限"选项中配置该角色拥有的具体权限
                </p>
              </div>
            </div>
          </div>
        </form>
      </div>
      
      <!-- 模态框底部 -->
      <div class="px-6 py-4 bg-gray-50 rounded-b-lg flex justify-end space-x-3">
        <button
          type="button"
          class="px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-colors"
          @click="handleClose"
          :disabled="loading"
        >
          取消
        </button>
        <button
          type="button"
          class="px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-colors"
          @click="handleSubmit"
          :disabled="loading"
        >
          <i v-if="loading" class="fa fa-spinner fa-spin mr-1"></i>
          创建角色
        </button>
      </div>
    </div>
  </div>
</template>

<script>
import { ref, watch } from 'vue';
import { useValidator } from '@/composables/useValidator';

export default {
  props: {
    // 控制模态框显示/隐藏
    visible: {
      type: Boolean,
      default: false
    }
  },
  emits: ['close', 'save'],
  setup(props, { emit }) {
    // 表单数据
    const formData = ref({
      name: '',
      code: '',
      description: ''
    });
    
    // 错误信息
    const errors = ref({});
    
    // 加载状态
    const loading = ref(false);
    
    // 验证器 composable
    const { validateRequired, validateCode } = useValidator();
    
    // 监听visible变化，重置表单
    watch(() => props.visible, (isVisible) => {
      if (isVisible) {
        // 当模态框显示时重置表单
        formData.value = {
          name: '',
          code: '',
          description: ''
        };
        errors.value = {};
        loading.value = false;
      }
    });
    
    // 表单验证
    const validateForm = () => {
      const newErrors = {};
      
      // 验证角色名称
      if (!validateRequired(formData.value.name)) {
        newErrors.name = '请输入角色名称';
      } else if (formData.value.name.length < 2 || formData.value.name.length > 50) {
        newErrors.name = '角色名称长度必须在2-50个字符之间';
      }
      
      // 验证角色编码
      if (!validateRequired(formData.value.code)) {
        newErrors.code = '请输入角色编码';
      } else if (!validateCode(formData.value.code)) {
        newErrors.code = '角色编码只能包含字母、数字和下划线';
      } else if (formData.value.code.length < 2 || formData.value.code.length > 30) {
        newErrors.code = '角色编码长度必须在2-30个字符之间';
      } else if (!/^[a-z]/.test(formData.value.code)) {
        newErrors.code = '角色编码必须以小写字母开头';
      }
      
      // 更新错误信息
      errors.value = newErrors;
      
      // 返回是否验证通过
      return Object.keys(newErrors).length === 0;
    };
    
    // 处理提交
    const handleSubmit = async () => {
      // 表单验证
      if (!validateForm()) {
        // 自动聚焦到第一个错误字段
        const firstErrorField = Object.keys(errors.value)[0];
        document.getElementById(firstErrorField)?.focus();
        return;
      }
      
      try {
        loading.value = true;
        // 触发保存事件，将表单数据传递给父组件
        emit('save', { ...formData.value });
      } catch (error) {
        console.error('提交表单失败:', error);
      } finally {
        loading.value = false;
      }
    };
    
    // 处理关闭
    const handleClose = () => {
      emit('close');
    };
    
    // 点击遮罩层关闭
    const handleOverlayClick = () => {
      handleClose();
    };
    
    return {
      formData,
      errors,
      loading,
      handleSubmit,
      handleClose,
      handleOverlayClick
    };
  }
};
</script>

<style scoped>
/* 动画效果 */
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes scaleIn {
  from { transform: scale(0.95); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

.fixed.inset-0 {
  animation: fadeIn 0.2s ease-out forwards;
}

.bg-white.rounded-lg {
  animation: scaleIn 0.2s ease-out forwards;
}
</style>
    